----------------------------------------------------------------------------------
-- Company: EIA-FR
-- Engineer: Robin Franzi
-- 
-- Create Date:    14:11:52 04/14/2009 
-- Design Name: 	 timeProcessingUnit
-- Module Name:    TPU - Description
-- Project Name: 		iTimer
-- Target Devices: 
-- Tool versions: 
-- Description: Simple stop watch
--
-- Dependencies: 
--
-- Revision: 
-- Revision 0.01 - File Created
-- Additional Comments: 
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity timeProcessingUnit is
    Port (	clockInput : in  STD_LOGIC;
				busMode : in STD_LOGIC_VECTOR (1 downto 0);
				busDecrement : in STD_LOGIC_VECTOR (1 downto 0);
				busIncrement : in STD_LOGIC_VECTOR (1 downto 0);
				busTime : out STD_LOGIC_VECTOR (12 downto 0):="0000000000000";
				alarmSignal : out  STD_LOGIC:='1');
end timeProcessingUnit;

architecture timeProcessingUnit_arch of timeProcessingUnit is


	-- declaration of the variables
	signal nextBusTime : STD_LOGIC_VECTOR (12 downto 0):="0000000000000";
	signal oldIncremet,oldDecrement:STD_LOGIC_VECTOR(1 downto 0):="00";
	signal nextAlarm : STD_LOGIC:='1';
	signal busWaitedTime : STD_LOGIC_VECTOR (11 downto 0):="000000000000";
	signal reStartTime : STD_LOGIC := '1';
	
begin	
-- waitedTime component
	waitedTimeC:entity work.waitedTime 
		port map
			(clockInput=> clockInput,
			reStartTime=>reStartTime,
			busWaitedTime=>busWaitedTime);
			
	-- register process
	registerProc: process(clockInput)
	begin
		if rising_edge(clockInput) then
			busTime <= nextBusTime;
			alarmSignal <= nextAlarm;
		end if;
	end process registerProc;
	
	
	-- process to calculate the future state

--main process, output circuit
	timeProcUnit: process(busIncrement,busDecrement,clockInput)
	begin
	if falling_edge(clockInput) THEN
		IF busMode = "00" THEN
				IF busIncrement/="00" THEN
					IF (nextBusTime+busIncrement) > conv_std_logic_vector(5999,13) THEN
						nextBusTime <= conv_std_logic_vector(0,13);
					ELSE 
						IF busIncrement ="11" THEN 
							nextBusTime <= nextBusTime + busIncrement + "11";
						ELSE
							nextBusTime <= nextBusTime + busIncrement;
						END IF;
					END IF;
				ELSIF busDecrement/="00" THEN
					IF (nextBusTime- busDecrement) > conv_std_logic_vector(6000,13) THEN
						nextBusTime <= conv_std_logic_vector(5999,13);
					ELSE 
						IF busDecrement ="11" THEN 
							nextBusTime <= nextBusTime - busDecrement -  "11";
						ELSE
							nextBusTime <= nextBusTime - busDecrement;
						END IF;
					END IF;
				END IF;
				nextAlarm <= '0';
		ELSIF busMode = "01" THEN
				reStartTime <= '0';
				if conv_integer (busWaitedTime) = 1000 then
					nextBusTime <= nextBusTime - 1;
					reStartTime <= '1';
				elsif busWaitedTime >= "001111101001" then
					reStartTime <= '0';
				end if;
				if nextBusTime = 0 then
					nextAlarm <= '1';
				end if;
		END IF;
	END IF;	
	end process timeProcUnit;
	
	
end timeProcessingUnit_arch;